import 'dart:async';

import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:qunaimedical/components/custom_divider.dart';
import 'package:qunaimedical/components/item_course.dart';
import 'package:qunaimedical/components/item_doctor.dart';
import 'package:qunaimedical/components/item_health_news.dart';
import 'package:qunaimedical/components/item_record_publish.dart';
import 'package:qunaimedical/models/Course.dart';
import 'package:qunaimedical/models/consultation_record.dart';
import 'package:qunaimedical/models/doctor.dart';
import 'package:qunaimedical/models/health_news.dart';
import 'package:qunaimedical/models/map_response.dart';
import 'package:qunaimedical/models/user.dart';
import 'package:qunaimedical/network/http.dart';
import 'package:qunaimedical/utils/dialog_utils.dart';
import 'package:qunaimedical/utils/event_bus_manager.dart';
import 'package:qunaimedical/utils/sp_utils.dart';
import 'package:qunaimedical/utils/toast_util.dart';
import 'package:qunaimedical/values/constants.dart';
import 'package:qunaimedical/values/urls.dart';
import 'package:sprintf/sprintf.dart';

enum FavoriteType { doctor, record, healthInfo, course }

/// 收藏的列表
class FavoriteList extends StatefulWidget {
  final FavoriteType type;

  const FavoriteList(this.type, {Key key}) : super(key: key);

  @override
  _FavoriteListState createState() => _FavoriteListState();
}

class _FavoriteListState extends State<FavoriteList> {
  List<Doctor> _doctors = [];
  List<ConsultationRecord> _records = [];
  List<HealthNews> _news = [];
  List<Course> _courses = [];

  RefreshController _refreshController =
      RefreshController(initialRefresh: false);

  // 是否有下一页
  int _nextPage = 1;
  StreamSubscription notifier;

  @override
  void initState() {
    super.initState();
    _fetchData();
    notifier = eventBus.on<EventBusManager>().listen((event) {
      if (event.eventKey == EventBusManager.favoriteRefresh) {
        _fetchData();
      }
    });
  }

  @override
  void dispose() {
    super.dispose();
    notifier.cancel();
  }

  @override
  Widget build(BuildContext context) {
    int itemCount;
    switch (widget.type) {
      case FavoriteType.doctor:
        itemCount = _doctors.length;
        break;
      case FavoriteType.record:
        itemCount = _records.length;
        break;
      case FavoriteType.healthInfo:
        itemCount = _news.length;
        break;
      case FavoriteType.course:
        itemCount = _courses.length;
        break;
    }
    return Scaffold(
      body: SmartRefresher(
        controller: _refreshController,
        enablePullDown: true,
        enablePullUp: _nextPage != 1,
        onRefresh: _fetchData,
        onLoading: _loadMore,
        child: ListView.separated(
          padding: EdgeInsets.only(top: 10, bottom: 50),
          itemBuilder: (c, i) {
            Widget child;
            switch (widget.type) {
              case FavoriteType.doctor:
                child = ItemDoctor(
                  _doctors[i],
                  onFavorite: () {
                    _removeFavorite(i);
                  },
                );
                break;
              case FavoriteType.record:
                child = ItemRecordPublish(item: _records[i]);
                break;
              case FavoriteType.healthInfo:
                child = ItemHealthNews(item: _news[i]);
                break;
              case FavoriteType.course:
                child = ItemCourse(item: _courses[i]);
                break;
            }
            return child;
          },
          separatorBuilder: (c, i) {
            return CustomDivider();
          },
          itemCount: itemCount,
        ),
      ),
    );
  }

  Map<String, dynamic> _buildParams() {
    Map<String, dynamic> params;
    switch (widget.type) {
      case FavoriteType.doctor:
        params = {
          "doctorAccountId": SPUtils.getUser().id,
          "whetherAppointed": "1"
        };
        break;
      case FavoriteType.course:
      case FavoriteType.healthInfo:
        params = {"accountId": SPUtils.getUser().id, "whetherAppointed": "1"};
        break;
      case FavoriteType.record:
        params = {"doctorId": SPUtils.getUser().id};
        break;
    }
    return params;
  }

  void _fetchData() async {
    String url;
    switch (widget.type) {
      case FavoriteType.doctor:
        url = Urls.DOCTOR_LIST;
        break;
      case FavoriteType.record:
        url = Urls.RECORD_PUBLISH_LIST;
        break;
      case FavoriteType.healthInfo:
        url = Urls.HEALTH_NEWS_LIST;
        break;
      case FavoriteType.course:
        url = Urls.COURSE_LIST;
        break;
    }
    var data = await XHttp.postJson(
        sprintf(url, [1, Constants.limit]), _buildParams());
    _refreshController.refreshCompleted();
    if (data != null) {
      var response = MapResponse.fromJson(data);
      if (response.code == 1) {
        if (response.data['pages'] == response.data['current']) {
          _nextPage = 1;
        } else {
          _nextPage = response.data['pages'] + 1;
        }
        setState(() {
          switch (widget.type) {
            case FavoriteType.doctor:
              _doctors = List.from(
                  response.data['records'].map((e) => Doctor.fromJson(e)));
              break;
            case FavoriteType.record:
              _records = List.from(response.data['records']
                  .map((e) => ConsultationRecord.fromJson(e)));
              break;
            case FavoriteType.healthInfo:
              _news = List.from(
                  response.data['records'].map((e) => HealthNews.fromJson(e)));
              break;
            case FavoriteType.course:
              _courses = List.from(
                  response.data['records'].map((e) => Course.fromJson(e)));
              break;
          }
        });
      } else {
        ToastUtil.show(response.msg, context);
      }
    }
  }

  void _loadMore() async {
    String url;
    switch (widget.type) {
      case FavoriteType.doctor:
        url = Urls.DOCTOR_LIST;
        break;
      case FavoriteType.record:
        url = Urls.RECORD_PUBLISH_LIST;
        break;
      case FavoriteType.healthInfo:
        url = Urls.HEALTH_NEWS_LIST;
        break;
      case FavoriteType.course:
        url = Urls.COURSE_LIST;
        break;
    }
    var result = await XHttp.postJson(
        sprintf(url, [_nextPage, Constants.limit]), _buildParams());
    _refreshController.loadComplete();
    if (result != null) {
      var response = MapResponse.fromJson(result);
      if (response.code == 1) {
        if (response.data['pages'] == response.data['current']) {
          _nextPage = 1;
        } else {
          _nextPage = response.data['pages'] + 1;
        }
        if (mounted) {
          setState(() {
            switch (widget.type) {
              case FavoriteType.doctor:
                _doctors.addAll(List.from(
                    response.data['records'].map((e) => Doctor.fromJson(e))));
                break;
              case FavoriteType.record:
                _records.addAll(List.from(response.data['records']
                    .map((e) => ConsultationRecord.fromJson(e))));
                break;
              case FavoriteType.healthInfo:
                _news.addAll(List.from(response.data['records']
                    .map((e) => HealthNews.fromJson(e))));
                break;
              case FavoriteType.course:
                _courses.addAll(List.from(
                    response.data['records'].map((e) => Course.fromJson(e))));
                break;
            }
          });
        }
      } else {
        ToastUtil.show(response.msg, context);
      }
    }
  }

  void _removeFavorite(int index) {
    DialogUtils.showAlertDialog(context, '提示', '确定取消收藏？', onPressed: () async {
      Navigator.pop(context);
      User user = SPUtils.getUser();
      if (user != null) {
        DialogUtils.showWaitDialog(context);
        var data = await XHttp.postJson(Urls.FAVORITE_REMOVE, {
          'accountId': user.id,
          'recordId': _doctors[index].id,
        });
        Navigator.pop(context);
        if (data != null) {
          Map<String, dynamic> response = data as Map<String, dynamic>;
          if (response['code'] == 1) {
            if (mounted) {
              setState(() {
                _doctors.removeAt(index);
              });
            }
          }
        }
      }
    });
  }
}
